/**
 * A simple class for defining an un-ordered pairing between any two objects.  Two Pair objects, A and B
 * are considered equal iff [ A.first.equals ( B.second ) or B.first.equals ( A.second ) ].  It is up 
 * to the contained objects to define the meaning of "equals".
 * 
 */
package util.data_structures;

/**
 * @author brian
 *
 */
public class Pair implements Comparable
{
	public Pair ( Object inFirst, Object inSecond )
	{
		first = inFirst;
		second = inSecond;
	
		if ( first instanceof Comparable && 
				second instanceof Comparable )
		{
			compFirst = (Comparable)inFirst;
			compSecond = (Comparable)inSecond;
		
			// Order the contained objects (just so Tree based datastructures can be used; 
			// this doesn't impact the equals operator)
			if ( compFirst.compareTo( compSecond ) > 0 )
			{
				compFirst = (Comparable)inSecond;
				compSecond = (Comparable)inFirst;	
			}
		}
	}
	
	public Object getFirst () { return first; };

	public Object getSecond () { return second; };
	
	public boolean equals ( Object inB )
	{	
		Pair B = (Pair)inB;
		return ( first.equals( B.first ) && second.equals( B.second ) ) || 
				( first.equals( B.second ) && second.equals( B.first ) );
	}
	
	public int hashCode() 
	{
		return first.hashCode() + second.hashCode();
	}
	
	public String toString ( )
	{
		return "[" + first.toString() +","+ second.toString() + "]";
	}
	
	public int compareTo ( Object inB )
	{
		Pair B = (Pair)inB;
		if ( compFirst == null || B.compFirst == null )
			throw new RuntimeException ( "The objects in the Pair are not orderable." );
		
		// Compare the first objects
		int nRes = compFirst.compareTo( B.compFirst );
		
		// If equal, compare the second objects
		if ( nRes == 0 )
			nRes = compSecond.compareTo( B.compSecond );
			
		return nRes; 		
	}
	
	private Comparable compFirst = null;
	private Comparable compSecond = null;
	
	private Object first = null;
	private Object second = null;
}
